﻿using DatabaseTransfer.Connections;
using DatabaseTransfer.Interfaces;
using DatabaseTransfer.Logs;
using DatabaseTransfer.Tables;
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseTransfer.Utils
{
    [Serializable()]
    public class DatabaseTransferSerializer : ISerializable
    {
        private static ILog logger = LogFactory.GetLogger(typeof(DatabaseTransferSerializer));
        public List<ColumnLinkage> LinkageList { get; set; }

        public Table SourceTable { get; set; }
        public Table DestinationTable { get; set; }

        public DatabaseConnector SourceConnector { get; set; }
        public DatabaseConnector DestinationConnector { get; set; }

        public DatabaseTransferSerializer(SerializationInfo info, StreamingContext ctxt)
        {
            this.LinkageList = (List<ColumnLinkage>)info.GetValue("LinkageList", typeof(List<ColumnLinkage>));
            this.SourceTable = (Table)info.GetValue("SourceTable", typeof(Table));
            this.DestinationTable = (Table)info.GetValue("DestinationTable", typeof(Table));
            this.SourceConnector = (DatabaseConnector)info.GetValue("SourceConnector", typeof(DatabaseConnector));
            this.DestinationConnector = (DatabaseConnector)info.GetValue("DestinationConnector", typeof(DatabaseConnector));
        }

        public DatabaseTransferSerializer() { }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("LinkageList", this.LinkageList);
            info.AddValue("SourceTable", this.SourceTable);
            info.AddValue("DestinationTable", this.DestinationTable);
            info.AddValue("SourceConnector", this.SourceConnector);
            info.AddValue("DestinationConnector", this.DestinationConnector);
        }

        public static bool Serialize(DatabaseTransferSerializer serializer, string fileName)
        {
            logger.Info("serializing file: " + fileName);
            using (Stream stream = File.Open(String.Format("{0}.dtf", fileName), FileMode.Create))
            {
                try
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(stream, serializer);
                    return true;
                }
                catch (Exception ex)
                {
                    logger.Error("Unable to serialize file", ex);
                    return false;
                }
            }
        }

        public static DatabaseTransferSerializer Deserialize(string fileName)
        {
            logger.Info("Deserializing File");
            DatabaseTransferSerializer serializer = null;
            try
            {
                using (Stream stream = File.Open(fileName, FileMode.Open))
                {
                    BinaryFormatter bin = new BinaryFormatter();
                    serializer = (DatabaseTransferSerializer)bin.Deserialize(stream);
                }
            }
            catch (Exception ex)
            {
                logger.Error("Unable to deseralize file " + fileName, ex);
            }

            return serializer;
        }
    }
}
